/*
 * @Author: DengZhiJun 1726768643@qq.com
 * @Date: 2025-01-17 20:58:37
 * @LastEditors: dengzhijun 1726768643@qq.com
 * @LastEditTime: 2025-01-24 13:41:49
 * @FilePath: /Tools/Test/Program_test.cpp
 * @Description: 
 * Copyright (c) 2025 by ${DengZhiJun} email: ${1726768643@qq.com}, All Rights Reserved.
 */
#ifndef PROGRAM_TEST_H
#define PROGRAM_TEST_H

#include "include/gtest.h"
#include "../Tool/include/Program.h"
#include "../Tool/include/Timer.h"
#include "../Tool/include/ILogger.h"
#include "../Tool/include/Random.h"
#include "nlohmann/json.hpp"
#include <chrono>

using namespace Tool;
using namespace nlohmann;
using namespace std;
using namespace std::chrono;

TEST(Program, Programprogram)
{
    return;
    Timer timer;
    Variant variantMap;
    variantMap["1"] = 12;
    variantMap["2"] = "nihao";
    std::string ni = variantMap["2"];
    std::cout << "ni: " << ni << std::endl;

    Program program;
    program.GetVariant() = variantMap;
    std::cout << "program: " << program.GetVariant() << std::endl;
    program.Save("program.bin", VariantSerializeType::Binary);
    program.Save("program.json", VariantSerializeType::Json);
    Program program1,program2,program3,program4;
    program1.Load("program.bin", VariantSerializeType::Binary);
    program3.Load("program.json", VariantSerializeType::Json);

    std::string path = "large_data.json";
    std::ifstream file(path);
    if (!file.is_open())
    {
        std::cerr << "Failed to Load path: " << path << std::endl;
        return;
    }
    std::string jsonStr((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    file.close();
    timer.Reset();
    nlohmann::json nlohmannJson = nlohmann::json::parse(jsonStr);
    LOG_INFO("nlohmannJson json序列化耗时%.3fms", timer.Elapsed());

    timer.Reset();
    Variant variant;
    variant.FromJsonString(jsonStr);
    LOG_INFO("Variant json序列化耗时%.3fms", timer.Elapsed());
}

TEST(Variant, VariantJson)
{
    auto funSerialize = [](int count)
    {
        Timer timer;
        json nlohmannJson;
        LOG_INFO("数据总量 : %d万", count * 4 / 10000);
        for (int i = 0; i < count; ++i)
        {
            json nlohmannJson2;
            nlohmannJson2["a"] = i;
            nlohmannJson2["b"] = (i % 2 == 0);
            nlohmannJson2["c"] = "value" + to_string(i);
            nlohmannJson2["d"] = static_cast<double>(i) / 100.0;
            nlohmannJson[to_string(i)] = std::move(nlohmannJson2);
        }
        LOG_INFO("nlohmannJson 写入耗时%.3fms", timer.Elapsed());

        for (int i = 0; i < count; ++i)
        {
            json json1;
            json1 = nlohmannJson[to_string(i)]["a"];
            json1 = nlohmannJson[to_string(i)]["b"];
            json1 = nlohmannJson[to_string(i)]["c"];
            json1 = nlohmannJson[to_string(i)]["d"];
        }
        LOG_INFO("nlohmannJson 读取耗时%.3fms", timer.Elapsed());

        timer.Reset();
        const std::string &njson =  nlohmannJson.dump();
        LOG_INFO("nlohmannJson 序列化耗时%.3fms", timer.Elapsed());

        timer.Reset();
        json njson2 = json::parse(njson);
        LOG_INFO("nlohmannJson 反序列化 %f毫秒", timer.Elapsed());

        VariantVector vec;
        vec.reserve(count);
        timer.Reset();
        for (int i = 0; i < count; ++i)
        {
            Variant variant2;
            variant2["a"] = i;
            variant2["b"] = (i % 2 == 0);
            variant2["c"] = "value" + to_string(i);
            variant2["d"] = static_cast<double>(i) / 100.0;
            vec.emplace_back(std::move(variant2));
        }
        LOG_INFO("variant 写入耗时%.3fms", timer.Elapsed());

        timer.Reset();
        for (int i = 0; i < count; ++i)
        {
            Variant variant2;
            variant2 = vec[i]["a"];
            variant2 = vec[i]["b"];
            variant2 = vec[i]["c"];
            variant2 = vec[i]["d"];
        }
        LOG_INFO("variant 读取耗时%.3fms", timer.Elapsed());
        Variant variant(std::move(vec));
        timer.Reset();
        const std::vector<uint8_t> &bstr = variant.ToBinaryString();
        LOG_INFO("variant ToBinaryString耗时%.3fms", timer.Elapsed());

        timer.Reset();
        Variant bstr1;
        bstr1.FromBinaryString(bstr);
        LOG_INFO("variant FromBinaryString耗时%.3fms", timer.Elapsed());

        bstr1.SerializeToFile("bstr1.json", VariantSerializeType::Json);
    };
    funSerialize(250000);
    LOG_INFO("======================");
    funSerialize(500000);
    LOG_INFO("======================");
    funSerialize(1000000);
    LOG_INFO("======================");
}

TEST(Variant, VariantRead)
{
    return;
    Timer timer;
    int count = 50000000;
    // 二进制写入 uint32_t（4字节/元素）
    ofstream os32("test32.bin", ios::binary);
    uint32_t val32 = 12;
    timer.Reset();
    for (int i = 0; i < count; ++i) 
    {
        os32.write(reinterpret_cast<const char*>(&val32), sizeof(val32));
    }
    os32.close();
    cout << "32位 二进制写入耗时: " << timer.Elapsed() << "ms" << endl;

    // 二进制写入 uint16_t（2字节/元素）
    ofstream os16("test16.bin", ios::binary);
    uint16_t val16 = 12;
    timer.Reset();
    for (int i = 0; i < count; ++i) 
    {
        os16.write(reinterpret_cast<const char*>(&val16), sizeof(val16));
    }
    os16.close();
    cout << "16位 二进制写入耗时: " << timer.Elapsed() << "ms" << endl;

    // 二进制读取 uint32_t
    ifstream is32("test32.bin", ios::binary);
    timer.Reset();
    for (int i = 0; i < count; ++i) 
    {
        is32.read(reinterpret_cast<char*>(&val32), sizeof(val32));
    }
    is32.close();
    cout << "32位 二进制读取耗时: " << timer.Elapsed() << "ms" << endl;

    // 二进制读取 uint16_t
    ifstream is16("test16.bin", ios::binary);
    timer.Reset();
    for (int i = 0; i < count; ++i) 
    {
        is16.read(reinterpret_cast<char*>(&val16), sizeof(val16));
    }
    is16.close();
    cout << "16位 二进制读取耗时: " << timer.Elapsed() << "ms" << endl;
}
#endif // PROGRAM_TEST_H
